package net.game;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.util.ArrayUtil;

import org.lwjgl.util.Rectangle;


public class ButtonGrid extends AbstractGUIComponent
{
	private int bWidth, bHeight;
	
	private final int[][] buttonMetaData;
	
	public final Button[][] buttons;
	
	public static final int DEFAULT_BUTTON = -1, BUTTON_SHIFT = 3,
			EXCLUDE_BUTTON = 0x0, 
			NORMAL_BUTTON = 0x1, 
			IGNORE_BUTTON = 0x2, 
			START_EXCLUDE_LINE = 0x4,
			START_NORMAL_LINE = 0x8,
			START_IGNORE_LINE = 0x16;

	public ButtonGrid(int x, int y, int xButtons, int yButtons, int bwidth, int bheight)
	{
		this(x,y,xButtons,yButtons,bwidth,bheight,null);	
	}
	
	public ButtonGrid(int x, int y, int xButtons, int yButtons, int bwidth, int bheight, int[][] data)
	{
		bWidth = bwidth;
		bHeight = bheight;
		
		buttons = new Button[yButtons][xButtons];
	
		buttonMetaData = new int[yButtons][xButtons];
		
		bounds = new Rectangle(x,y,xButtons * bWidth, yButtons * bHeight);
		
		if (data == null)
		{
			data = new int[yButtons][xButtons];
			ArrayUtil.fill2d(data, NORMAL_BUTTON);
		}
		
		ArrayUtil.ensureDimensions(data, yButtons, xButtons);
		
		initButtons();
		
		setData(data);
	}
	
	private void initButtons()
	{
		for(int y = 0; y < buttons.length; y ++)
		{
			for(int x = 0; x < buttons[0].length; x ++)
			{
				buttons[y][x] = new Button(bounds.getX() + (x * bWidth), bounds.getY() + (y * bHeight), bWidth, bHeight);
			}
		}
	}
	
	public void setData(int [][] data)
	{
		final int mHeight = ArrayUtil.height(buttons);
		
		data = ArrayUtil.ensureDimensions(data, mHeight, buttons.length);
		
		int start, current;
		
		System.out.println(ArrayUtil.toString(data).replace("]", "]\n"));
		
		for (int y = 0; y < buttons.length; y++)
		{
			start = -1;
			for (int x = 0; x < buttons[0].length; x++)
			{
				if (start != -1)
				{
					current = start;
				}
				else
				{
					current = data[y][x];
				}
				
				if (current > 2)
				{
					current >>= BUTTON_SHIFT;
					start = current;
				}
				
				buttonMetaData[y][x] = current;
			}
		}
	}
	
	public void setData(int x, int y, int[] data)
	{
		int start = -1;
		
		for(int _x = 0; _x < data.length; _x++)
		{
			if(start != -1)
			{
				data[_x] = start;
			}
			
			if (data[_x] > 2)
			{
				start = data[_x] >> BUTTON_SHIFT;
			}
			
			buttonMetaData[y][x + _x] = data[_x];
		}
	}
	
	public void setData(int x, int y, int datum)
	{
		if (datum > 2)
		{
			datum >>= 3;
			Arrays.fill(buttonMetaData[y], x, buttonMetaData[y].length - 1, datum);
		}
		
		buttonMetaData[y][x] = datum;
		
		if (datum > 0)
		{
			buttons[y][x] = new Button(bounds.getX() + x * bWidth, bounds.getY() + y * bHeight, bWidth, bHeight);
		}
	}
	
	public void setActionListener(int x, int y, ActionListener a)
	{
		buttons[y][x].setActionListener(a);
	}
	
	public Button getButton(int x, int y)
	{
		return buttons[y][x];
	}
	
	public List<Button> getButtons()
	{
		return ArrayUtil.asList(buttons);
	} 
	
	public List<Button> getButtons(int datum)
	{
		ArrayList<Button> result = new ArrayList<>(buttons.length * buttons[0].length);
		
		for(int y = 0; y < buttons.length; y++)
		{
			for(int x = 0; x < buttons[0].length; x ++)
			{
				if (datum == buttonMetaData[y][x] || (buttonMetaData[y][x] & datum) != 0)
				{
					result.add(buttons[y][x]);
				}
			}
		}
		
		return result;
	}
	
	public void render()
	{
		for (int y = buttons.length - 1; y >= 0; y--)
		{
			for (int x = buttons[0].length - 1; x >= 0; x --)
			{
				switch (buttonMetaData[y][x])
				{
				case IGNORE_BUTTON:
					buttons[y][x].renderBasic();
					break;
				case NORMAL_BUTTON:
					buttons[y][x].render();
				}
			}
		}
	}
}
